home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: dir.c
-
- Copyright (C) 1998-2004 Christophe GRENIER <grenier@cgsecurity.org>
-
- This software is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
- #include <stdio.h>
- #include <ctype.h> /* toupper */
- #include <string.h>
- #include <stdlib.h>
- #include <time.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include "types.h"
- #include "common.h"
- #include "fat.h"
- #include "lang.h"
- #include "fnctdsk.h"
- #include "testdisk.h"
- #include "intrface.h"
- #include "dir.h"
- static const char *monstr[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
- static void mode_string (const unsigned int mode, char *str);
- static char ftypelet (unsigned int bits);
-
- static char ftypelet (unsigned int bits)
- {
- #ifdef LINUX_S_ISBLK
- if (LINUX_S_ISBLK (bits))
- return 'b';
- #endif
- if (LINUX_S_ISCHR (bits))
- return 'c';
- if (LINUX_S_ISDIR (bits))
- return 'd';
- if (LINUX_S_ISREG (bits))
- return '-';
- #ifdef LINUX_S_ISFIFO
- if (LINUX_S_ISFIFO (bits))
- return 'p';
- #endif
- #ifdef LINUX_S_ISLNK
- if (LINUX_S_ISLNK (bits))
- return 'l';
- #endif
- #ifdef LINUX_S_ISSOCK
- if (LINUX_S_ISSOCK (bits))
- return 's';
- #endif
- #ifdef LINUX_S_ISMPC
- if (LINUX_S_ISMPC (bits))
- return 'm';
- #endif
- #ifdef LINUX_S_ISNWK
- if (LINUX_S_ISNWK (bits))
- return 'n';
- #endif
- #ifdef LINUX_S_ISDOOR
- if (LINUX_S_ISDOOR (bits))
- return 'D';
- #endif
- #ifdef LINUX_S_ISCTG
- if (LINUX_S_ISCTG (bits))
- return 'C';
- #endif
- #ifdef LINUX_S_ISOFD
- if (LINUX_S_ISOFD (bits))
- /* off line, with data */
- return 'M';
- #endif
- #ifdef LINUX_S_ISOFL
- /* off line, with no data */
- if (LINUX_S_ISOFL (bits))
- return 'M';
- #endif
- return '?';
- }
-
- void mode_string (const unsigned int mode, char *str)
- {
- str[0] = ftypelet(mode);
- str[1] = mode & LINUX_S_IRUSR ? 'r' : '-';
- str[2] = mode & LINUX_S_IWUSR ? 'w' : '-';
- str[3] = mode & LINUX_S_IXUSR ? 'x' : '-';
- str[4] = mode & LINUX_S_IRGRP ? 'r' : '-';
- str[5] = mode & LINUX_S_IWGRP ? 'w' : '-';
- str[6] = mode & LINUX_S_IXGRP ? 'x' : '-';
- str[7] = mode & LINUX_S_IROTH ? 'r' : '-';
- str[8] = mode & LINUX_S_IWOTH ? 'w' : '-';
- str[9] = mode & LINUX_S_IXOTH ? 'x' : '-';
- str[10]='\0';
- #ifdef LINUX_S_ISUID
- if (mode & LINUX_S_ISUID)
- {
- if (str[3] != 'x')
- /* Set-uid, but not executable by owner. */
- str[3] = 'S';
- else
- str[3] = 's';
- }
- #endif
- #ifdef LINUX_S_ISGID
- if (mode & LINUX_S_ISGID)
- {
- if (str[6] != 'x')
- /* Set-gid, but not executable by group. */
- str[6] = 'S';
- else
- str[6] = 's';
- }
- #endif
- #ifdef LINUX_S_ISVTX
- if (mode & LINUX_S_ISVTX)
- {
- if (str[9] != 'x')
- /* Sticky, but not executable by others. */
- str[9] = 'T';
- else
- str[9] = 't';
- }
- #endif
- }
-
- void dir_aff_log(const t_param_disk *disk_car, const t_diskext *partition, const t_dir_data *dir_data, const t_file_data*dir_list)
- {
- const t_file_data *current_file;
- aff_part_rapport(disk_car,partition);
- if(dir_data!=NULL)
- {
- ecrit_rapport("Directory %s\n",dir_data->current_directory);
- }
- for(current_file=dir_list;current_file!=NULL;current_file=current_file->next)
- {
- struct tm *tm_p;
- char datestr[80];
- char str[11];
- if(current_file->filestat.st_mtime)
- {
- tm_p = localtime(¤t_file->filestat.st_mtime);
- sprintf(datestr, "%2d-%s-%4d %02d:%02d",
- tm_p->tm_mday, monstr[tm_p->tm_mon],
- 1900 + tm_p->tm_year, tm_p->tm_hour,
- tm_p->tm_min);
- } else {
- strncpy(datestr, " ",sizeof(datestr));
- }
- mode_string(current_file->filestat.st_mode,str);
- ecrit_rapport("%s %5u %5u ",
- str, current_file->filestat.st_uid, current_file->filestat.st_gid);
- ecrit_rapport("%7llu", (long long unsigned int)current_file->filestat.st_size);
- ecrit_rapport(" %s %s\n", datestr, current_file->name);
- }
- }
-
- long int dir_aff(t_param_disk *disk_car, const t_diskext *partition, t_dir_data *dir_data, const t_file_data*dir_list, const unsigned long int inode)
- {
- /* Return value
- * -1: quit
- * 1: back
- * other: new inode
- * */
- int quit;
- int offset=0;
- int pos_num=0;
- const t_file_data *current_file;
- const t_file_data *pos=dir_list;
- aff_copy(dir_data->window);
- wmove(dir_data->window,4,0);
- aff_part(dir_data->window,AFF_PART_NONL,disk_car,partition);
- mvwaddstr(dir_data->window,5,0,"Use arrow keys to change directory, enter to quit");
- wmove(dir_data->window,6,0);
- wdoprintf(dir_data->window,"Directory %s\n",dir_data->current_directory);
- do
- {
- int i;
- int car;
- for(i=0,current_file=dir_list;(current_file!=NULL) && (i<offset);current_file=current_file->next,i++);
- for(i=offset;(current_file!=NULL) &&((i-offset)<INTER_STRUCTURE);i++,current_file=current_file->next)
- {
- struct tm *tm_p;
- char str[11];
- char datestr[80];
- wmove(dir_data->window,8+i-offset,0);
- wclrtoeol(dir_data->window); /* before addstr for BSD compatibility */
- if(current_file==pos)
- wstandout(dir_data->window);
- if(current_file->filestat.st_mtime!=0)
- {
- tm_p = localtime(¤t_file->filestat.st_mtime);
- sprintf(datestr, "%2d-%s-%4d %02d:%02d",
- tm_p->tm_mday, monstr[tm_p->tm_mon],
- 1900 + tm_p->tm_year, tm_p->tm_hour,
- tm_p->tm_min);
- } else {
- strncpy(datestr, " ",sizeof(datestr));
- }
- mode_string(current_file->filestat.st_mode,str);
- wdoprintf(dir_data->window, "%s %5u %5u ",
- str, current_file->filestat.st_uid, current_file->filestat.st_gid);
- wdoprintf(dir_data->window, "%7llu", (long long unsigned int)current_file->filestat.st_size);
- wdoprintf(dir_data->window, " %s %s\n", datestr, current_file->name);
- if(current_file==pos)
- wstandend(dir_data->window);
- }
- wrefresh(dir_data->window);
- car=wgetch(dir_data->window);
- quit=0;
- switch(car)
- {
- case 'q':
- case '\r':
- case '\n':
- case 'M':
- case KEY_ENTER:
- #ifdef PADENTER
- case PADENTER:
- #endif
- quit=1;
- break;
- }
- if(dir_list!=NULL)
- {
- switch(car)
- {
- case KEY_UP:
- if(pos->prev!=NULL)
- {
- pos=pos->prev;
- pos_num--;
- }
- if(pos_num<offset)
- offset--;
- break;
- case KEY_DOWN:
- if(pos->next!=NULL)
- {
- pos=pos->next;
- pos_num++;
- }
- if(pos_num>=offset+INTER_STRUCTURE)
- offset++;
- break;
- case '+':
- case ' ':
- case KEY_RIGHT:
- if((pos!=NULL) && (LINUX_S_ISDIR(pos->filestat.st_mode)!=0))
- {
- unsigned long int new_inode=pos->filestat.st_ino;
- if(new_inode!=inode)
- {
- if(strcmp(pos->name,"..")==0)
- return 1;
- if(strlen(dir_data->current_directory)+1+strlen(pos->name)<sizeof(dir_data->current_directory)-1)
- {
- if(strcmp(dir_data->current_directory,"/"))
- strcat(dir_data->current_directory,"/");
- strcat(dir_data->current_directory,pos->name);
- return (long int)new_inode;
- }
- }
- }
- break;
- case KEY_PPAGE:
- for(i=0;(i<INTER_STRUCTURE-1)&&(pos->prev!=NULL);i++)
- {
- pos=pos->prev;
- pos_num--;
- if(pos_num<offset)
- offset--;
- }
- break;
- case KEY_NPAGE:
- for(i=0;(i<INTER_STRUCTURE-1)&&(pos->next!=NULL);i++)
- {
- pos=pos->next;
- pos_num++;
- if(pos_num>=offset+INTER_STRUCTURE)
- offset++;
- }
- break;
- }
- }
- switch(car)
- {
- case '-':
- case KEY_LEFT:
- return 1;
- }
- } while(quit==0);
- return -1;
- }
-
- void delete_list_file(t_file_data *file_list)
- {
- t_file_data *current_file=file_list;
- /* Libere la memoire */
- while(current_file!=NULL)
- {
- t_file_data *next=current_file->next;
- FREE(current_file);
- current_file=next;
- }
- }
-
- int dir_partition(t_param_disk *disk_car, const t_diskext *partition, t_dir_data *dir_data, const unsigned long int inode)
- {
- t_file_data *dir_list;
- long int new_inode;
- if(dir_data->debug!=0)
- ecrit_rapport("\ndir_partition inode=%ld\n",inode);
- dir_list=dir_data->get_dir(disk_car,partition,dir_data,inode);
- dir_aff_log(disk_car, partition, dir_data, dir_list);
- do
- {
- unsigned int current_directory_namelength=strlen(dir_data->current_directory);
- new_inode=dir_aff(disk_car,partition,dir_data,dir_list,inode);
- if(new_inode==0 || new_inode>1)
- {
- if(dir_partition(disk_car, partition, dir_data, (unsigned long int)new_inode)<0)
- { /* quit */
- delete_list_file(dir_list);
- return -1;
- }
- /* back */
- dir_data->current_directory[current_directory_namelength]='\0';
- }
- } while(new_inode==0 || new_inode>1);
- delete_list_file(dir_list);
- return new_inode;
- }
-
-